// // 线段树其实就是基于分治的思想来进行

// // zdl:: 尝试解决树状数组的问题

// // * 写出线段树的基本结构
const int num(5e5 + 10);
#define lc p << 1     // 左孩子节点
#define rc p << 1 | 1 // 右孩子节点
#include <iostream>
#include <string>

using namespace std;
using ll = long long;

ll a[num];
struct node
{
    int  l, r;
    ll sum;

} tr[num << 2];
void pushV(int p) { tr[p].sum = tr[lc].sum + tr[rc].sum; }

void bulid(int p, int l, int r)
{
    // 先初始化
    tr[p] = {l, r, a[l]};
    if (l == r)
    {
        // tr[p].sum = a[l];
        return;
    }
    int mid = (l + r) >> 1;
    bulid(lc, l, mid);
    bulid(rc, mid + 1, r);
    pushV(p);
}
void add(int p, int x, ll k)
{
    int l = tr[p].l, r = tr[p].r;

    if (l == r && l == x)
    {
        tr[p].sum += k;
        return;
    }
    int mid = (l + r) >> 1;

    if (x <= mid)
        add(lc, x, k);
    else
        add(rc, x, k);
    // 搞清楚节点中的编号和左右区间的位置，这个不能混淆
    pushV(p);
}

// 呢没智商还是分治的问题，还是很简单的，现在就是需要记住相关的一些东西
ll query(int p, int x, int y)
{
    int l = tr[p].l, r = tr[p].r;
    if (x <= l && y >= r)
        return tr[p].sum;

    int mid = (l + r) >> 1;
    ll sum = 0;
    if (x <= mid)
        sum += query(lc, x, y);
    if (y >= mid + 1)
        sum += query(rc, x, y);

    return sum;
}
int main()
{

    // cout << num << endl;
    ll n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    // * 构建树
    bulid(1, 1, n);
    while (m--)
    {
        int op, x, y;

        cin >> op >> x >> y;
        if (op == 1)
        {
            add(1, x, y);
        }
        else
        {
            cout << query(1, x, y) << endl;
        }
    }

    return 0;
}

// #include <iostream>
// using namespace std;
// #define lc p << 1
// #define rc p << 1 | 1
// typedef long long LL;
// const int N = 5e5 + 10;
// int n, m;
// LL a[N];
// struct node
// {
//     int l, r;
//     LL sum;
// } tr[N << 2];
// void pushup(int p)
// {
//     tr[p].sum = tr[lc].sum + tr[rc].sum;
// }
// void build(int p, int l, int r)
// {
//     tr[p] = {l, r, a[l]};
//     if (l == r)
//         return;
//     int mid = (l + r) >> 1;
//     build(lc, l, mid);
//     build(rc, mid + 1, r);
//     pushup(p);
// }
// // 单点修改
// void modify(int p, int x, LL k)
// {
//     int l = tr[p].l, r = tr[p].r;
//     if (x == l && r == x)
//     {
//         tr[p].sum += k;
//         return;
//     }
//     int mid = (l + r) >> 1;
//     if (x <= mid)
//         modify(lc, x, k);
//     else
//         modify(rc, x, k);
//     pushup(p);
// }
// // 区间查询
// LL query(int p, int x, int y)
// {
//     int l = tr[p].l, r = tr[p].r;
//     if (x <= l && r <= y)
//         return tr[p].sum;
//     int mid = (l + r) >> 1;
//     LL sum = 0;
//     if (x <= mid)
//         sum += query(lc, x, y);
//     if(y > mid) sum += query(rc, x, y);
//     return sum;
// }
// int main()
// {
//     cin >> n >> m;
//     for (int i = 1; i <= n; i++)
//         cin >> a[i];
//     build(1, 1, n);
//     while (m--)
//     {
//         int op, x, y;
//         cin >> op >> x >> y;
//         if (op == 1)
//             modify(1, x, y);
//         else
//             cout << query(1, x, y) << endl;
//     }
//     return 0;
// }